### To Do 

# Actual statistics for relationships between temperature and CTmax, size, and fecundity
# Pull residuals from CTmax ~ temperature model, and examine the change over time in lab and the relationship with fecundity

Copepod Collection

Copepods were collected at approximately weekly intervals from Lake Champlain (Burlington Fishing Pier). Plankton was collected from the top 3 meters using a 250 um mesh net. Copepods from 12 collections were used to make a total of 263 thermal limit measurements. Over this time period, collection temperatures ranged from 10.5 to 26.5°C.

Temperature Variation

Water temperatures in Lake Champlain reached a minimum in February. Sampling for this project began during the Spring warming period. Temperature variability (both ranges and variance) increase with temperature, but are strongly affected by the length of time period examined.

# Lake Champlain near Burlington, VT
siteNumber = "04294500"
ChamplainInfo = readNWISsite(siteNumber)
parameterCd = "00010"
startDate = "2023-01-01"
endDate = ""
#statCd = c("00001", "00002","00003", "00011") # 1 - max, 2 - min, 3 = mean

# Constructs the URL for the data wanted then downloads the data
url = constructNWISURL(siteNumbers = siteNumber, parameterCd = parameterCd, 
                       startDate = startDate, endDate = endDate, service = "uv")

temp_data = importWaterML1(url, asDateTime = T) %>% 
  mutate("date" = as.Date(dateTime)) %>% 
  select(date, "temp" = X_00010_00000)


## Daily values
daily_temp_data = temp_data %>%
  ungroup() %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            med_temp = median(temp),
            var_temp = var(temp), 
            min_temp = min(temp), 
            max_temp = max(temp)) %>% 
  mutate("range_temp" = max_temp - min_temp)

daily_plot = daily_temp_data %>% 
  pivot_longer(cols = c(-date),
               names_to = "parameter", 
               values_to = "temp") %>% 
  ggplot(aes(x = date, y = temp, colour = parameter)) + 
  geom_line(linewidth = 1) + 
  scale_colour_manual(values = c(
    "mean_temp" = "olivedrab3",
    "med_temp" = "seagreen3",
    "max_temp" = "tomato",  
    "min_temp" = "dodgerblue",
    "range_temp" = "goldenrod3",
    "var_temp" = "darkgoldenrod1"
  )) + 
  scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) + 
  ggtitle("Daily Values") + 
  labs(y = "Temperature (°C)",
       x = "") + 
  theme_bw(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
## Defining the function to get predictor values for periods of different lengths
get_predictors = function(daily_values, raw_temp, n_days){
  prefix = str_replace_all(xfun::numbers_to_words(n_days), pattern = " ", replacement = "-")
  
  mean_values = daily_values %>% 
    ungroup() %>% 
    mutate(mean_max = slide_vec(.x = max_temp, .f = mean, .before = n_days, .complete = T),
           mean_min = slide_vec(.x = min_temp, .f = mean, .before = n_days, .complete = T),
           mean_range = slide_vec(.x = range_temp, .f = mean, .before = n_days, .complete = T)) %>% 
    select(date, mean_max, mean_min, mean_range) %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))
  
  period_values = raw_temp %>% 
    mutate(mean = slide_index_mean(temp, i = date, before = days(n_days), 
                                   na_rm = T),
           max = slide_index_max(temp, i = date, before = days(n_days), 
                                 na_rm = T),
           min = slide_index_min(temp, i = date, before = days(n_days),
                                 na_rm = T),
           med = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 na_rm = T, .f = median),
           var = slide_index_dbl(temp, .i = date, .before = days(n_days), 
                                 .f = var),
           range = max - min) %>%  
    select(-temp) %>%  
    distinct() %>% 
    rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))%>% 
    inner_join(mean_values, by = c("date")) %>%  
    drop_na()
  
  return(period_values)
}
## Getting predictor variables for different periods

### ONE WEEK
week_temps = get_predictors(daily_values = daily_temp_data, 
                            raw_temp = temp_data, 
                            n_days = 7)

week_plot = week_temps %>% 
  pivot_longer(cols = c(-date),
               names_to = "parameter", 
               values_to = "temp") %>% 
  filter(parameter %in% c("seven_day_mean",
                          "seven_day_med",
                          "seven_day_max", 
                          "seven_day_min", 
                          "seven_day_var",
                          "seven_day_range")) %>% 
  mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>% 
  ggplot(aes(x = date, y = temp, colour = parameter)) + 
  geom_line(linewidth = 1) + 
  scale_colour_manual(values = c(
    "mean_temp" = "olivedrab3",
    "med_temp" = "seagreen3",
    "max_temp" = "tomato",  
    "min_temp" = "dodgerblue",
    "range_temp" = "goldenrod3",
    "var_temp" = "darkgoldenrod1"
  )) + 
  scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) + 
  ggtitle("One Week") + 
  labs(y = "Temperature (°C)",
       x = "") + 
  theme_bw(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))


### TWO WEEKS
two_week_temps = get_predictors(daily_values = daily_temp_data, 
                                raw_temp = temp_data, 
                                n_days = 14)

two_week_plot = two_week_temps %>% 
  pivot_longer(cols = c(-date),
               names_to = "parameter", 
               values_to = "temp") %>% 
  filter(parameter %in% c("fourteen_day_mean",
                          "fourteen_day_med",
                          "fourteen_day_max", 
                          "fourteen_day_min", 
                          "fourteen_day_var",
                          "fourteen_day_range")) %>% 
  mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>% 
  ggplot(aes(x = date, y = temp, colour = parameter)) + 
  geom_line(linewidth = 1) + 
  scale_colour_manual(values = c(
    "mean_temp" = "olivedrab3",
    "med_temp" = "seagreen3",
    "max_temp" = "tomato",  
    "min_temp" = "dodgerblue",
    "range_temp" = "goldenrod3",
    "var_temp" = "darkgoldenrod1"
  )) + 
  scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) + 
  ggtitle("Two Weeks") + 
  labs(y = "Temperature (°C)",
       x = "") + 
  theme_bw(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))


### FOUR WEEKS
four_week_temps = get_predictors(daily_values = daily_temp_data, 
                                 raw_temp = temp_data, 
                                 n_days = 28)

four_week_plot = four_week_temps %>% 
  pivot_longer(cols = c(-date),
               names_to = "parameter", 
               values_to = "temp") %>% 
  filter(parameter %in% c("twenty-eight_day_mean",
                          "twenty-eight_day_med",
                          "twenty-eight_day_max", 
                          "twenty-eight_day_min", 
                          "twenty-eight_day_var",
                          "twenty-eight_day_range")) %>% 
  mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>% 
  ggplot(aes(x = date, y = temp, colour = parameter)) + 
  geom_line(linewidth = 1) + 
  scale_colour_manual(values = c(
    "mean_temp" = "olivedrab3",
    "med_temp" = "seagreen3",
    "max_temp" = "tomato",  
    "min_temp" = "dodgerblue",
    "range_temp" = "goldenrod3",
    "var_temp" = "darkgoldenrod1"
  )) + 
  scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) + 
  ggtitle("Four Weeks") + 
  labs(y = "Temperature (°C)",
       x = "") + 
  theme_bw(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))


### EIGHT WEEKS
eight_week_temps = get_predictors(daily_values = daily_temp_data, 
                                  raw_temp = temp_data, 
                                  n_days = 56)

eight_week_plot = eight_week_temps %>% 
  pivot_longer(cols = c(-date),
               names_to = "parameter", 
               values_to = "temp") %>% 
  filter(parameter %in% c("fifty-six_day_mean",
                          "fifty-six_day_med",
                          "fifty-six_day_max", 
                          "fifty-six_day_min", 
                          "fifty-six_day_var",
                          "fifty-six_day_range")) %>% 
  mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>% 
  ggplot(aes(x = date, y = temp, colour = parameter)) + 
  geom_line(linewidth = 1) + 
  scale_colour_manual(values = c(
    "mean_temp" = "olivedrab3",
    "med_temp" = "seagreen3",
    "max_temp" = "tomato",  
    "min_temp" = "dodgerblue",
    "range_temp" = "goldenrod3",
    "var_temp" = "darkgoldenrod1"
  )) + 
  scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) + 
  ggtitle("Eight Weeks") + 
  labs(y = "Temperature (°C)",
       x = "") + 
  theme_bw(base_size = 20) + 
  theme(panel.grid = element_blank(),
        axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))

ggarrange(daily_plot, week_plot, two_week_plot, four_week_plot, eight_week_plot, 
          common.legend = T, nrow = 1, legend = "bottom")

## Daily values for the period examined by dataset
collection_conditions = temp_data %>%
  ungroup() %>% 
  group_by(date) %>% 
  summarise(mean_temp = mean(temp),
            med_temp = median(temp),
            var_temp = var(temp), 
            min_temp = min(temp), 
            max_temp = max(temp)) %>% 
  mutate("range_temp" = max_temp - min_temp,
         date = as.Date(date)) %>% 
  ungroup() %>%  
  filter(date >= (min(as.Date(full_data$collection_date)) - 7))

## Mean female thermal limits for each species, grouped by collection
species_summaries = full_data %>%  
  #filter(sex == "female") %>% 
  group_by(sp_name, collection_date, collection_temp) %>%  
  summarise("mean_ctmax" = mean(ctmax),
            "sample_size" = n(),
            "ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
            "ctmax_var" = var(ctmax), 
            "mean_size" = mean(size),
            "size_st_err" = (sd(size) / sqrt(sample_size)),
            "size_var" = var(size)) %>%  
  ungroup() %>% 
  complete(sp_name, collection_date) %>% 
  arrange(desc(sample_size))

ggplot() + 
  geom_vline(data = unique(select(full_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date),
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) +
  geom_point(data = species_summaries, 
             aes(x = as.Date(collection_date), y = mean_ctmax, colour = sp_name, size = sample_size)) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species",
       size = "Sample Size") + 
  theme_matt() + 
  theme(legend.position = "right")


size_timeseries = ggplot() + 
  geom_vline(data = unique(select(full_data, collection_date)), 
             aes(xintercept = as.Date(collection_date)),
             colour = "grey90",
             linewidth = 1) + 
  geom_line(data = collection_conditions, 
            aes(x = as.Date(date), y = mean_temp),
            colour = "black", 
            linewidth = 2) + 
  # geom_errorbar(data = species_summaries,
  #               aes(x = as.Date(collection_date), 
  #                   ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
  #                   colour = sp_name),
  #               position = position_dodge(width = 1),
  #               width = 5, linewidth = 1) + 
  geom_point(data = species_summaries, 
             aes(x = as.Date(collection_date), y = mean_size * 40, colour = sp_name),
             position = position_dodge(width = 1),
             size = 4) + 
  scale_colour_manual(values = species_cols) + 
  scale_y_continuous(
    name = "Temperature", # Features of the first axis
    sec.axis = sec_axis(~./40, name="Prosome Length (mm)"), # Add a second axis and specify its features
    breaks = c(0,5,10,15,20,25,30)
  ) + 
  labs(x = "Date", 
       y = "Temperature (°C)", 
       colour = "Species") + 
  theme_matt() + 
  theme(legend.position = "right")

#ggarrange(ctmax_timeseries, size_timeseries, common.legend = T, legend = "bottom")
## Combine data, then pull out values for each collection date
date_list = as.Date(unique(full_data$collection_date))

temp_predictors = daily_temp_data %>% 
  full_join(week_temps, by = c("date")) %>% 
  full_join(two_week_temps, by = c("date")) %>% 
  full_join(four_week_temps, by = c("date")) %>% 
  full_join(eight_week_temps, by = c("date")) %>% 
  filter(date %in% date_list)

A set of predictors variables were assembled from the continuous temperature data set based on conditions during the day of collection, the week before collections, and the preceding two, four, and eight week periods. This is a preliminary analysis for now. Shown here are the top three factors. Species with no significant predictor or limited collection date distributions were excluded.

corr_vals = full_data %>%  
  filter(sp_name != "Senecella calanoides") %>%
  filter(sp_name != "Limnocalanus macrurus") %>%
  mutate(collection_date = as.Date(collection_date)) %>% 
  full_join(temp_predictors, join_by(collection_date == date)) %>% 
  pivot_longer(cols = c(collection_temp, mean_temp:tail(names(.), 1)),
               values_to = "value", 
               names_to = "predictor") %>%  
  group_by(sp_name, predictor) %>% 
  summarise(correlation = cor.test(ctmax, value)$estimate,
            p.value = cor.test(ctmax, value)$p.value,
            ci_low = cor.test(ctmax, value)$conf.int[1],
            ci_high = cor.test(ctmax, value)$conf.int[2]) %>% 
  mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig."))

corr_vals %>%  
  filter(sig == "Sig.") %>% 
  drop_na(correlation) %>% 
  group_by(sp_name) %>%
  arrange(desc(correlation)) %>% 
  slice_head(n = 3) %>% 
  select("Species" = sp_name, "Predictor" = predictor, "Correlation" = correlation, "P-Value" = p.value) %>% 
  knitr::kable(align = "c")
Species Predictor Correlation P-Value
Epischura lacustris fifty-six_day_max 0.7776250 7.8e-06
Epischura lacustris twenty-eight_day_max 0.7775023 7.8e-06
Epischura lacustris seven_day_mean_max 0.7765511 8.1e-06
Leptodiaptomus minutus fourteen_day_med 0.7089108 0.0e+00
Leptodiaptomus minutus min_temp 0.7082184 0.0e+00
Leptodiaptomus minutus mean_temp 0.7079993 0.0e+00
Skistodiaptomus oregonensis seven_day_max 0.6992135 0.0e+00
Skistodiaptomus oregonensis fourteen_day_max 0.6973601 0.0e+00
Skistodiaptomus oregonensis twenty-eight_day_max 0.6951473 0.0e+00

Trait Variation

ctmax_plot = full_data %>% 
  mutate( #sp_name = str_replace(sp_name, pattern = " ",
    #                              replacement = "\n"),
    sp_name = fct_reorder(sp_name, ctmax, mean)) %>% 
  ggplot(aes(y = sp_name, x = ctmax)) + 
  geom_point(aes(colour= sp_name_sub),
             position = position_dodge(width = 0.3),
             size = 4) + 
  scale_colour_manual(values = species_cols) + 
  xlab(NULL) + 
  labs(y = "",
       x = "CTmax (°C)",
       colour = "Group") + 
  theme_matt() + 
  theme(legend.position = "none")

size_plot = full_data %>% 
  mutate(sp_name = fct_reorder(sp_name, ctmax, mean)) %>% 
  ggplot(aes(y = sp_name, x = size)) + 
  geom_point(aes(colour= sp_name_sub),
             position = position_dodge(width = 0.3),
             size = 4) + 
  scale_colour_manual(values = species_cols) + 
  labs(x = "Prosome Length (mm)",
       y = "", 
       colour = "Group") + 
  guides(color = guide_legend(ncol = 1)) +
  theme_matt(base_size = ) + 
  theme(legend.position = "right",
        axis.text.y = element_blank(),
        plot.margin = margin(0, 0, 0, 0,"cm"))

trait_plot = ctmax_plot + size_plot
trait_plot

full_data %>%  
  drop_na(fecundity) %>%  
  ggplot(aes(x = fecundity, fill = sp_name_sub)) + 
  facet_wrap(.~sp_name_sub, ncol = 1) + 
  geom_histogram(binwidth = 2) + 
  scale_fill_manual(values = species_cols) + 
  labs(x = "Fecundity (# Eggs)") +
  theme_matt_facets() + 
  theme(legend.position = "none")

Variation with temperature

ctmax_temp = ggplot(full_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) + 
  geom_smooth(method = "lm", linewidth = 3) +
  geom_point(size = 3) + 
  labs(x = "Collection Temperature (°C)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

size_temp = ggplot(filter(full_data, sex != "juvenile"), aes(x = collection_temp, y = size, colour = sp_name)) + 
  geom_smooth(method = "lm", linewidth = 3) +
  geom_point(size = 3) + 
  labs(x = "Collection Temperature (°C)", 
       y = "Length (mm)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

wt_temp = ggplot(full_data, aes(x = collection_temp, y = warming_tol, colour = sp_name)) + 
  geom_smooth(method = "lm", linewidth = 3) +
  geom_point(size = 3) + 
  labs(x = "Collection Temperature (°C)", 
       y = "Warming Tolerance (°C)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

eggs_temp = ggplot(full_data, aes(x = collection_temp, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", linewidth = 3) +
  geom_point(size = 3) + 
  labs(x = "Collection Temperature (°C)", 
       y = "Fecundity (# Eggs)",
       colour = "Species")  + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggarrange(ctmax_temp, size_temp, wt_temp, eggs_temp, 
          common.legend = T, legend = "right")

ctmax_temp.model = lm(data = full_data, ctmax ~ collection_temp * sp_name)

knitr::kable(car::Anova(ctmax_temp.model))
Sum Sq Df F value Pr(>F)
collection_temp 224.539478 1 178.7447772 0.0000000
sp_name 1174.077704 6 155.7708693 0.0000000
collection_temp:sp_name 2.204612 3 0.5849942 0.6253559
Residuals 316.562807 252 NA NA

ctmax_resids = cbind(full_data, "resids" = ctmax_temp.model$residuals)
ggplot(ctmax_resids, aes(x = days_in_lab, y = resids, colour = sp_name)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 4) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  scale_x_continuous(breaks = c(0:3)) + 
  labs(x = "Days in lab", 
       y = "CTmax Residuals") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt_facets() + 
  theme(legend.position = "none")

Given the long generation times of these copepods, decreases in trait variance may indicate selection over the seasonal cycle. Shown below are the variance in observed CTmax and size, plotted against collection date. Variance decreases in Skistodiaptomus, but this pattern is driven by a single collection with high variance early in the year. Size variance increases slightly in Skistodiaptomus. Variance in both CTmax and size is fairly constant in Leptodiaptomus minutus, the only other species collected across the entire set of samples thus far.

ggplot(drop_na(species_summaries, ctmax_var), aes(x = as.Date(collection_date), y = ctmax_var, colour = sp_name)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 2) + 
  geom_smooth(method = "lm", se = F) + 
  labs(x = "Collection Temp. (°C)", 
       y = "CTmax Variance") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt_facets() + 
  theme(legend.position = "none")


ggplot(drop_na(species_summaries, size_var), aes(x = as.Date(collection_date), y = size_var, colour = sp_name)) + 
  facet_wrap(sp_name~.) + 
  geom_point(size = 2) + 
  geom_smooth(method = "lm", se = F) + 
  labs(x = "Collection Temp. (°C)", 
       y = "Size Variance") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt_facets() + 
  theme(legend.position = "none")

Sex and stage variation in thermal limits

Previous sections have generally lumped juvenile, female, and male individuals together. There may be important stage- or sex-specific differences in CTmax though. For several species, we have measurements for individuals in different stages or of different sexes.

sex_sample_sizes = ctmax_resids %>%  
  group_by(sp_name, sex) %>%  
  summarise(num = n()) %>%  
  pivot_wider(id_cols = sp_name,
              names_from = sex, 
              values_from = num,
              values_fill = 0) %>% 
  select("Species" = sp_name, "Juvenile" = juvenile, "Female" = female, "Male" = male)

knitr::kable(sex_sample_sizes, align = "c")
Species Juvenile Female Male
Epischura lacustris 9 8 7
Leptodiaptomus minutus 5 94 27
Leptodiaptomus sicilis 0 10 0
Leptodora kindti 1 0 11
Limnocalanus macrurus 2 4 1
Senecella calanoides 0 1 0
Skistodiaptomus oregonensis 2 65 16

The female-male and female-juvenile comparisons show that there are generally no differences in thermal limits between these groups.

ctmax_resids %>% 
  filter(sp_name %in% filter(sex_sample_sizes, Male > 0, Female > 0)$Species & 
           sex != "juvenile") %>% 
  ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) + 
  facet_wrap(sp_name~., ncol = 2) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  geom_point(size = 3,
             alpha = 0.5,
             position = position_jitter(height = 0, width = 0.05)) +  
  labs(x = "Sex", 
       y = "CTmax Residuals") + 
  scale_colour_manual(values = species_cols) + 
  theme_bw(base_size = 18) + 
  theme(legend.position = "none", 
        panel.grid = element_blank())

ctmax_resids %>% 
  filter(sp_name %in% filter(sex_sample_sizes, Juvenile > 0 & Female > 0)$Species & 
           sex != "male") %>% 
  ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) + 
  facet_wrap(sp_name~., ncol = 1) + 
  geom_smooth(method = "lm", se = F, linewidth = 1) + 
  geom_point(size = 3,
             alpha = 0.5,
             position = position_jitter(height = 0, width = 0.05)) +  
  labs(x = "Sex", 
       y = "CTmax (°C)") + 
  scale_colour_manual(values = species_cols) + 
  theme_bw(base_size = 18) + 
  theme(legend.position = "none", 
        panel.grid = element_blank())

Trait Correlations

ggplot(full_data, aes(x = size, y = ctmax, colour = sp_name)) + 
  geom_smooth(data = full_data, 
              aes(x = size, y = ctmax),
              method = "lm", 
              colour ="black", 
              linewidth = 2.5) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 4) + 
  labs(x = "Length (mm)", 
       y = "CTmax (°C)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggplot(ctmax_resids, aes(x = size, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 4) + 
  labs(x = "Prosome length (mm)", 
       y = "Fecundity (# Eggs)",
       colour = "Species") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

ggplot(ctmax_resids, aes(x = ctmax, y = fecundity, colour = sp_name)) + 
  geom_smooth(method = "lm", se = F, linewidth = 2) + 
  geom_point(size = 4) + 
  labs(x = "CTmax (°C)", 
       y = "Fecundity (# Eggs)") + 
  scale_colour_manual(values = species_cols) + 
  theme_matt() + 
  theme(legend.position = "right")

LS0tCnRpdGxlOiBTZWFzb25hbGl0eSBpbiBMYWtlIENoYW1wbGFpbiBDb3BlcG9kIFRoZXJtYWwgTGltaXRzCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3IgdG8tZG99CiMjIyBUbyBEbyAKCiMgQWN0dWFsIHN0YXRpc3RpY3MgZm9yIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiB0ZW1wZXJhdHVyZSBhbmQgQ1RtYXgsIHNpemUsIGFuZCBmZWN1bmRpdHkKIyBQdWxsIHJlc2lkdWFscyBmcm9tIENUbWF4IH4gdGVtcGVyYXR1cmUgbW9kZWwsIGFuZCBleGFtaW5lIHRoZSBjaGFuZ2Ugb3ZlciB0aW1lIGluIGxhYiBhbmQgdGhlIHJlbGF0aW9uc2hpcCB3aXRoIGZlY3VuZGl0eQoKYGBgCgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgZ2dwdWJyOjp0aGVtZV9wdWJyKGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGRhcmtfdGV4dCksCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gbWlkX3RleHQpLAogICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygzLCAwLCAwLCAwKSwgIm1tIikpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygwLCA1LCAwLCAwKSwgIm1tIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5nbGUgPSA5MCksCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9YmFzZV9zaXplICogMC45KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAwLjksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiksCiAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUsImNtIikKICAgICkKfQoKdGhlbWVfbWF0dF9mYWNldHMgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXJrX3RleHQgPSAiZ3JleTIwIil7CiAgbWlkX3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVsyXQogIGxpZ2h0X3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVszXQogIAogIHRoZW1lX2J3KGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9CgpzcGVjaWVzX2NvbHMgPSBjKCJMZXB0b2RpYXB0b211cyBtaW51dHVzIiA9ICIjZmZkMDI5IiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyBqdXZlbmlsZSIgPSAiI2UzZDhhZiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMgbWFsZSIgPSAiI2ZmZTg5NiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiID0gIiNEODZGMjkiLAogICAgICAgICAgICAgICAgICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIG1hbGUiID0gIiNFMjhDMDAiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiID0gIiNDNUMzNUEiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMgbWFsZSIgPSAiI2U2ZTZhYSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIGp1dmVuaWxlIiA9ICJwbHVtMSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIG1hbGUiID0gInBsdW0zIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMiID0gInBsdW00IiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyIgPSAic2t5Ymx1ZTQiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIG1hbGUiID0gInNreWJsdWUzIiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyBqdXZlbmlsZSIgPSAic2t5Ymx1ZSIsIAogICAgICAgICAgICAgICAgICJTZW5lY2VsbGEgY2FsYW5vaWRlcyIgPSAiZGFya3NlYWdyZWVuMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkgbWFsZSIgPSAibGlnaHRibHVlMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkiID0gImxpZ2h0Ymx1ZTQiLAogICAgICAgICAgICAgICAgICJMZXB0b2RvcmEga2luZHRpIGp1dmVuaWxlIiA9ICJsaWdodGJsdWUiKQpgYGAKCiMjIENvcGVwb2QgQ29sbGVjdGlvbgoKQ29wZXBvZHMgd2VyZSBjb2xsZWN0ZWQgYXQgYXBwcm94aW1hdGVseSB3ZWVrbHkgaW50ZXJ2YWxzIGZyb20gTGFrZSBDaGFtcGxhaW4gKEJ1cmxpbmd0b24gRmlzaGluZyBQaWVyKS4gUGxhbmt0b24gd2FzIGNvbGxlY3RlZCBmcm9tIHRoZSB0b3AgMyBtZXRlcnMgdXNpbmcgYSAyNTAgdW0gbWVzaCBuZXQuIENvcGVwb2RzIGZyb20gYHIgbGVuZ3RoKHVuaXF1ZShmdWxsX2RhdGEkY29sbGVjdGlvbl9kYXRlKSlgIGNvbGxlY3Rpb25zIHdlcmUgdXNlZCB0byBtYWtlIGEgdG90YWwgb2YgYHIgZGltKGZ1bGxfZGF0YSlbMV1gIHRoZXJtYWwgbGltaXQgbWVhc3VyZW1lbnRzLiBPdmVyIHRoaXMgdGltZSBwZXJpb2QsIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmVzIHJhbmdlZCBmcm9tIGByIHBhc3RlKG1pbihmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwgIiB0byAiLCBtYXgoZnVsbF9kYXRhJGNvbGxlY3Rpb25fdGVtcCksIHNlcCA9ICIiKWDCsEMuIAoKIyMgVGVtcGVyYXR1cmUgVmFyaWF0aW9uIApXYXRlciB0ZW1wZXJhdHVyZXMgaW4gTGFrZSBDaGFtcGxhaW4gcmVhY2hlZCBhIG1pbmltdW0gaW4gRmVicnVhcnkuIFNhbXBsaW5nIGZvciB0aGlzIHByb2plY3QgYmVnYW4gZHVyaW5nIHRoZSBTcHJpbmcgd2FybWluZyBwZXJpb2QuIFRlbXBlcmF0dXJlIHZhcmlhYmlsaXR5IChib3RoIHJhbmdlcyBhbmQgdmFyaWFuY2UpIGluY3JlYXNlIHdpdGggdGVtcGVyYXR1cmUsIGJ1dCBhcmUgc3Ryb25nbHkgYWZmZWN0ZWQgYnkgdGhlIGxlbmd0aCBvZiB0aW1lIHBlcmlvZCBleGFtaW5lZC4gICAgCgpgYGB7ciBwdWxsaW5nLXRlbXAtZGF0YX0KIyBMYWtlIENoYW1wbGFpbiBuZWFyIEJ1cmxpbmd0b24sIFZUCnNpdGVOdW1iZXIgPSAiMDQyOTQ1MDAiCkNoYW1wbGFpbkluZm8gPSByZWFkTldJU3NpdGUoc2l0ZU51bWJlcikKcGFyYW1ldGVyQ2QgPSAiMDAwMTAiCnN0YXJ0RGF0ZSA9ICIyMDIzLTAxLTAxIgplbmREYXRlID0gIiIKI3N0YXRDZCA9IGMoIjAwMDAxIiwgIjAwMDAyIiwiMDAwMDMiLCAiMDAwMTEiKSAjIDEgLSBtYXgsIDIgLSBtaW4sIDMgPSBtZWFuCgojIENvbnN0cnVjdHMgdGhlIFVSTCBmb3IgdGhlIGRhdGEgd2FudGVkIHRoZW4gZG93bmxvYWRzIHRoZSBkYXRhCnVybCA9IGNvbnN0cnVjdE5XSVNVUkwoc2l0ZU51bWJlcnMgPSBzaXRlTnVtYmVyLCBwYXJhbWV0ZXJDZCA9IHBhcmFtZXRlckNkLCAKICAgICAgICAgICAgICAgICAgICAgICBzdGFydERhdGUgPSBzdGFydERhdGUsIGVuZERhdGUgPSBlbmREYXRlLCBzZXJ2aWNlID0gInV2IikKCnRlbXBfZGF0YSA9IGltcG9ydFdhdGVyTUwxKHVybCwgYXNEYXRlVGltZSA9IFQpICU+JSAKICBtdXRhdGUoImRhdGUiID0gYXMuRGF0ZShkYXRlVGltZSkpICU+JSAKICBzZWxlY3QoZGF0ZSwgInRlbXAiID0gWF8wMDAxMF8wMDAwMCkKCgojIyBEYWlseSB2YWx1ZXMKZGFpbHlfdGVtcF9kYXRhID0gdGVtcF9kYXRhICU+JQogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtZWRfdGVtcCA9IG1lZGlhbih0ZW1wKSwKICAgICAgICAgICAgdmFyX3RlbXAgPSB2YXIodGVtcCksIAogICAgICAgICAgICBtaW5fdGVtcCA9IG1pbih0ZW1wKSwgCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXApKSAlPiUgCiAgbXV0YXRlKCJyYW5nZV90ZW1wIiA9IG1heF90ZW1wIC0gbWluX3RlbXApCgpkYWlseV9wbG90ID0gZGFpbHlfdGVtcF9kYXRhICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoLWRhdGUpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXJhbWV0ZXIiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiAgZ2d0aXRsZSgiRGFpbHkgVmFsdWVzIikgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCmBgYHtyIHByZWRpY3RvcnMtZnVuY3Rpb259CiMjIERlZmluaW5nIHRoZSBmdW5jdGlvbiB0byBnZXQgcHJlZGljdG9yIHZhbHVlcyBmb3IgcGVyaW9kcyBvZiBkaWZmZXJlbnQgbGVuZ3RocwpnZXRfcHJlZGljdG9ycyA9IGZ1bmN0aW9uKGRhaWx5X3ZhbHVlcywgcmF3X3RlbXAsIG5fZGF5cyl7CiAgcHJlZml4ID0gc3RyX3JlcGxhY2VfYWxsKHhmdW46Om51bWJlcnNfdG9fd29yZHMobl9kYXlzKSwgcGF0dGVybiA9ICIgIiwgcmVwbGFjZW1lbnQgPSAiLSIpCiAgCiAgbWVhbl92YWx1ZXMgPSBkYWlseV92YWx1ZXMgJT4lIAogICAgdW5ncm91cCgpICU+JSAKICAgIG11dGF0ZShtZWFuX21heCA9IHNsaWRlX3ZlYygueCA9IG1heF90ZW1wLCAuZiA9IG1lYW4sIC5iZWZvcmUgPSBuX2RheXMsIC5jb21wbGV0ZSA9IFQpLAogICAgICAgICAgIG1lYW5fbWluID0gc2xpZGVfdmVjKC54ID0gbWluX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCksCiAgICAgICAgICAgbWVhbl9yYW5nZSA9IHNsaWRlX3ZlYygueCA9IHJhbmdlX3RlbXAsIC5mID0gbWVhbiwgLmJlZm9yZSA9IG5fZGF5cywgLmNvbXBsZXRlID0gVCkpICU+JSAKICAgIHNlbGVjdChkYXRlLCBtZWFuX21heCwgbWVhbl9taW4sIG1lYW5fcmFuZ2UpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKQogIAogIHBlcmlvZF92YWx1ZXMgPSByYXdfdGVtcCAlPiUgCiAgICBtdXRhdGUobWVhbiA9IHNsaWRlX2luZGV4X21lYW4odGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFfcm0gPSBUKSwKICAgICAgICAgICBtYXggPSBzbGlkZV9pbmRleF9tYXgodGVtcCwgaSA9IGRhdGUsIGJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWluID0gc2xpZGVfaW5kZXhfbWluKHRlbXAsIGkgPSBkYXRlLCBiZWZvcmUgPSBkYXlzKG5fZGF5cyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWVkID0gc2xpZGVfaW5kZXhfZGJsKHRlbXAsIC5pID0gZGF0ZSwgLmJlZm9yZSA9IGRheXMobl9kYXlzKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCwgLmYgPSBtZWRpYW4pLAogICAgICAgICAgIHZhciA9IHNsaWRlX2luZGV4X2RibCh0ZW1wLCAuaSA9IGRhdGUsIC5iZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuZiA9IHZhciksCiAgICAgICAgICAgcmFuZ2UgPSBtYXggLSBtaW4pICU+JSAgCiAgICBzZWxlY3QoLXRlbXApICU+JSAgCiAgICBkaXN0aW5jdCgpICU+JSAKICAgIHJlbmFtZV93aXRoKCB+IHBhc3RlKHByZWZpeCwgImRheSIsIC54LCBzZXAgPSAiXyIpLCAuY29scyA9IGMoLWRhdGUpKSU+JSAKICAgIGlubmVyX2pvaW4obWVhbl92YWx1ZXMsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgIAogICAgZHJvcF9uYSgpCiAgCiAgcmV0dXJuKHBlcmlvZF92YWx1ZXMpCn0KYGBgCgoKYGBge3IgcHJlZGljdG9ycy1hbmQtcGxvdHMsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD01fQojIyBHZXR0aW5nIHByZWRpY3RvciB2YXJpYWJsZXMgZm9yIGRpZmZlcmVudCBwZXJpb2RzCgojIyMgT05FIFdFRUsKd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSA3KQoKd2Vla19wbG90ID0gd2Vla190ZW1wcyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ0ZW1wIikgJT4lIAogIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJzZXZlbl9kYXlfbWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9tZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfbWF4IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9taW4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X3ZhciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9yYW5nZSIpKSAlPiUgCiAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAogICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKICAgICJyYW5nZV90ZW1wIiA9ICJnb2xkZW5yb2QzIiwKICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiAgKSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKyAKICBnZ3RpdGxlKCJPbmUgV2VlayIpICsgCiAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKICAgICAgIHggPSAiIikgKyAKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKCgojIyMgVFdPIFdFRUtTCnR3b193ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gMTQpCgp0d29fd2Vla19wbG90ID0gdHdvX3dlZWtfdGVtcHMgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInBhcmFtZXRlciIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidGVtcCIpICU+JSAKICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygiZm91cnRlZW5fZGF5X21lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfbWVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X21heCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfbWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV92YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfcmFuZ2UiKSkgJT4lIAogIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKICAgICJtaW5fdGVtcCIgPSAiZG9kZ2VyYmx1ZSIsCiAgICAicmFuZ2VfdGVtcCIgPSAiZ29sZGVucm9kMyIsCiAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgogICkpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsgCiAgZ2d0aXRsZSgiVHdvIFdlZWtzIikgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQoKCiMjIyBGT1VSIFdFRUtTCmZvdXJfd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gMjgpCgpmb3VyX3dlZWtfcGxvdCA9IGZvdXJfd2Vla190ZW1wcyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ0ZW1wIikgJT4lIAogIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJ0d2VudHktZWlnaHRfZGF5X21lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X21lZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWF4IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfdmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9yYW5nZSIpKSAlPiUgCiAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAogICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKICAgICJyYW5nZV90ZW1wIiA9ICJnb2xkZW5yb2QzIiwKICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiAgKSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKyAKICBnZ3RpdGxlKCJGb3VyIFdlZWtzIikgKyAKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQoKCiMjIyBFSUdIVCBXRUVLUwplaWdodF93ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IDU2KQoKZWlnaHRfd2Vla19wbG90ID0gZWlnaHRfd2Vla190ZW1wcyAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ0ZW1wIikgJT4lIAogIGZpbHRlcihwYXJhbWV0ZXIgJWluJSBjKCJmaWZ0eS1zaXhfZGF5X21lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21lZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWF4IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfbWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfdmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlmdHktc2l4X2RheV9yYW5nZSIpKSAlPiUgCiAgbXV0YXRlKHBhcmFtZXRlciA9IHBhc3RlKHdvcmQocGFyYW1ldGVyLCBzdGFydCA9IDMsIHNlcCA9IGZpeGVkKCJfIikpLCAiX3RlbXAiLCBzZXAgPSAiIikpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoCiAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKICAgICJtZWRfdGVtcCIgPSAic2VhZ3JlZW4zIiwKICAgICJtYXhfdGVtcCIgPSAidG9tYXRvIiwgIAogICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKICAgICJyYW5nZV90ZW1wIiA9ICJnb2xkZW5yb2QzIiwKICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiAgKSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYXMuRGF0ZShjKCIyMDIzLTAxLTAxIiwgIjIwMjMtMDQtMDEiLCAiMjAyMy0wNy0wMSIpKSkgKyAKICBnZ3RpdGxlKCJFaWdodCBXZWVrcyIpICsgCiAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKICAgICAgIHggPSAiIikgKyAKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKCmdnYXJyYW5nZShkYWlseV9wbG90LCB3ZWVrX3Bsb3QsIHR3b193ZWVrX3Bsb3QsIGZvdXJfd2Vla19wbG90LCBlaWdodF93ZWVrX3Bsb3QsIAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFQsIG5yb3cgPSAxLCBsZWdlbmQgPSAiYm90dG9tIikKYGBgCgpgYGB7ciBjdG1heC10aW1lc2VyaWVzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NX0KIyMgRGFpbHkgdmFsdWVzIGZvciB0aGUgcGVyaW9kIGV4YW1pbmVkIGJ5IGRhdGFzZXQKY29sbGVjdGlvbl9jb25kaXRpb25zID0gdGVtcF9kYXRhICU+JQogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtZWRfdGVtcCA9IG1lZGlhbih0ZW1wKSwKICAgICAgICAgICAgdmFyX3RlbXAgPSB2YXIodGVtcCksIAogICAgICAgICAgICBtaW5fdGVtcCA9IG1pbih0ZW1wKSwgCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXApKSAlPiUgCiAgbXV0YXRlKCJyYW5nZV90ZW1wIiA9IG1heF90ZW1wIC0gbWluX3RlbXAsCiAgICAgICAgIGRhdGUgPSBhcy5EYXRlKGRhdGUpKSAlPiUgCiAgdW5ncm91cCgpICU+JSAgCiAgZmlsdGVyKGRhdGUgPj0gKG1pbihhcy5EYXRlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKSAtIDcpKQoKIyMgTWVhbiBmZW1hbGUgdGhlcm1hbCBsaW1pdHMgZm9yIGVhY2ggc3BlY2llcywgZ3JvdXBlZCBieSBjb2xsZWN0aW9uCnNwZWNpZXNfc3VtbWFyaWVzID0gZnVsbF9kYXRhICU+JSAgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBncm91cF9ieShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUsIGNvbGxlY3Rpb25fdGVtcCkgJT4lICAKICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCksCiAgICAgICAgICAgICJzYW1wbGVfc2l6ZSIgPSBuKCksCiAgICAgICAgICAgICJjdG1heF9zdF9lcnIiID0gKHNkKGN0bWF4KSAvIHNxcnQoc2FtcGxlX3NpemUpKSwKICAgICAgICAgICAgImN0bWF4X3ZhciIgPSB2YXIoY3RtYXgpLCAKICAgICAgICAgICAgIm1lYW5fc2l6ZSIgPSBtZWFuKHNpemUpLAogICAgICAgICAgICAic2l6ZV9zdF9lcnIiID0gKHNkKHNpemUpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAic2l6ZV92YXIiID0gdmFyKHNpemUpKSAlPiUgIAogIHVuZ3JvdXAoKSAlPiUgCiAgY29tcGxldGUoc3BfbmFtZSwgY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgYXJyYW5nZShkZXNjKHNhbXBsZV9zaXplKSkKCmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICMgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fY3RtYXggLSBjdG1heF9zdF9lcnIsIHltYXggPSBtZWFuX2N0bWF4ICsgY3RtYXhfc3RfZXJyLAogICMgICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BfbmFtZSksCiAgIyAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAjICAgICAgICAgICAgICAgd2lkdGggPSA1LCBsaW5ld2lkdGggPSAxKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsIAogICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBtZWFuX2N0bWF4LCBjb2xvdXIgPSBzcF9uYW1lLCBzaXplID0gc2FtcGxlX3NpemUpKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJEYXRlIiwgCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIsCiAgICAgICBzaXplID0gIlNhbXBsZSBTaXplIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKc2l6ZV90aW1lc2VyaWVzID0gZ2dwbG90KCkgKyAKICBnZW9tX3ZsaW5lKGRhdGEgPSB1bmlxdWUoc2VsZWN0KGZ1bGxfZGF0YSwgY29sbGVjdGlvbl9kYXRlKSksIAogICAgICAgICAgICAgYWVzKHhpbnRlcmNlcHQgPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSkpLAogICAgICAgICAgICAgY29sb3VyID0gImdyZXk5MCIsCiAgICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fbGluZShkYXRhID0gY29sbGVjdGlvbl9jb25kaXRpb25zLCAKICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGRhdGUpLCB5ID0gbWVhbl90ZW1wKSwKICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIiwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgIyBnZW9tX2Vycm9yYmFyKGRhdGEgPSBzcGVjaWVzX3N1bW1hcmllcywKICAjICAgICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIAogICMgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fY3RtYXggLSBjdG1heF9zdF9lcnIsIHltYXggPSBtZWFuX2N0bWF4ICsgY3RtYXhfc3RfZXJyLAogICMgICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BfbmFtZSksCiAgIyAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAjICAgICAgICAgICAgICAgd2lkdGggPSA1LCBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoZGF0YSA9IHNwZWNpZXNfc3VtbWFyaWVzLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gbWVhbl9zaXplICogNDAsIGNvbG91ciA9IHNwX25hbWUpLAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDEpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKAogICAgbmFtZSA9ICJUZW1wZXJhdHVyZSIsICMgRmVhdHVyZXMgb2YgdGhlIGZpcnN0IGF4aXMKICAgIHNlYy5heGlzID0gc2VjX2F4aXMofi4vNDAsIG5hbWU9IlByb3NvbWUgTGVuZ3RoIChtbSkiKSwgIyBBZGQgYSBzZWNvbmQgYXhpcyBhbmQgc3BlY2lmeSBpdHMgZmVhdHVyZXMKICAgIGJyZWFrcyA9IGMoMCw1LDEwLDE1LDIwLDI1LDMwKQogICkgKyAKICBsYWJzKHggPSAiRGF0ZSIsIAogICAgICAgeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgojZ2dhcnJhbmdlKGN0bWF4X3RpbWVzZXJpZXMsIHNpemVfdGltZXNlcmllcywgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJib3R0b20iKQpgYGAKCgpgYGB7ciBwdWxsaW5nLXByZWRpY3RvcnN9CiMjIENvbWJpbmUgZGF0YSwgdGhlbiBwdWxsIG91dCB2YWx1ZXMgZm9yIGVhY2ggY29sbGVjdGlvbiBkYXRlCmRhdGVfbGlzdCA9IGFzLkRhdGUodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKQoKdGVtcF9wcmVkaWN0b3JzID0gZGFpbHlfdGVtcF9kYXRhICU+JSAKICBmdWxsX2pvaW4od2Vla190ZW1wcywgYnkgPSBjKCJkYXRlIikpICU+JSAKICBmdWxsX2pvaW4odHdvX3dlZWtfdGVtcHMsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgCiAgZnVsbF9qb2luKGZvdXJfd2Vla190ZW1wcywgYnkgPSBjKCJkYXRlIikpICU+JSAKICBmdWxsX2pvaW4oZWlnaHRfd2Vla190ZW1wcywgYnkgPSBjKCJkYXRlIikpICU+JSAKICBmaWx0ZXIoZGF0ZSAlaW4lIGRhdGVfbGlzdCkKYGBgCgpBIHNldCBvZiBwcmVkaWN0b3JzIHZhcmlhYmxlcyB3ZXJlIGFzc2VtYmxlZCBmcm9tIHRoZSBjb250aW51b3VzIHRlbXBlcmF0dXJlIGRhdGEgc2V0IGJhc2VkIG9uIGNvbmRpdGlvbnMgZHVyaW5nIHRoZSBkYXkgb2YgY29sbGVjdGlvbiwgdGhlIHdlZWsgYmVmb3JlIGNvbGxlY3Rpb25zLCBhbmQgdGhlIHByZWNlZGluZyB0d28sIGZvdXIsIGFuZCBlaWdodCB3ZWVrIHBlcmlvZHMuIFRoaXMgaXMgYSBwcmVsaW1pbmFyeSBhbmFseXNpcyBmb3Igbm93LiBTaG93biBoZXJlIGFyZSB0aGUgdG9wIHRocmVlIGZhY3RvcnMuIFNwZWNpZXMgd2l0aCBubyBzaWduaWZpY2FudCBwcmVkaWN0b3Igb3IgbGltaXRlZCBjb2xsZWN0aW9uIGRhdGUgZGlzdHJpYnV0aW9ucyB3ZXJlIGV4Y2x1ZGVkLiAKCmBgYHtyIHByZWRpY3Rvci1jb3JyZWxhdGlvbnN9CmNvcnJfdmFscyA9IGZ1bGxfZGF0YSAlPiUgIAogIGZpbHRlcihzcF9uYW1lICE9ICJTZW5lY2VsbGEgY2FsYW5vaWRlcyIpICU+JQogIGZpbHRlcihzcF9uYW1lICE9ICJMaW1ub2NhbGFudXMgbWFjcnVydXMiKSAlPiUKICBtdXRhdGUoY29sbGVjdGlvbl9kYXRlID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSAlPiUgCiAgZnVsbF9qb2luKHRlbXBfcHJlZGljdG9ycywgam9pbl9ieShjb2xsZWN0aW9uX2RhdGUgPT0gZGF0ZSkpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMoY29sbGVjdGlvbl90ZW1wLCBtZWFuX3RlbXA6dGFpbChuYW1lcyguKSwgMSkpLAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWUiLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJlZGljdG9yIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lLCBwcmVkaWN0b3IpICU+JSAKICBzdW1tYXJpc2UoY29ycmVsYXRpb24gPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGVzdGltYXRlLAogICAgICAgICAgICBwLnZhbHVlID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRwLnZhbHVlLAogICAgICAgICAgICBjaV9sb3cgPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGNvbmYuaW50WzFdLAogICAgICAgICAgICBjaV9oaWdoID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRjb25mLmludFsyXSkgJT4lIAogIG11dGF0ZShzaWcgPSBpZmVsc2UocC52YWx1ZSA8MC4wNSwgIlNpZy4iLCAiTm9uIFNpZy4iKSkKCmNvcnJfdmFscyAlPiUgIAogIGZpbHRlcihzaWcgPT0gIlNpZy4iKSAlPiUgCiAgZHJvcF9uYShjb3JyZWxhdGlvbikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JQogIGFycmFuZ2UoZGVzYyhjb3JyZWxhdGlvbikpICU+JSAKICBzbGljZV9oZWFkKG4gPSAzKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJQcmVkaWN0b3IiID0gcHJlZGljdG9yLCAiQ29ycmVsYXRpb24iID0gY29ycmVsYXRpb24sICJQLVZhbHVlIiA9IHAudmFsdWUpICU+JSAKICBrbml0cjo6a2FibGUoYWxpZ24gPSAiYyIpCmBgYAoKIyMgVHJhaXQgVmFyaWF0aW9uIApgYGB7ciBjdG1heC1hbmQtc2l6ZS1zdW0tcGxvdCwgZmlnLndpZHRoPTIwLCBmaWcuaGVpZ2h0PTV9CmN0bWF4X3Bsb3QgPSBmdWxsX2RhdGEgJT4lIAogIG11dGF0ZSggI3NwX25hbWUgPSBzdHJfcmVwbGFjZShzcF9uYW1lLCBwYXR0ZXJuID0gIiAiLAogICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gIlxuIiksCiAgICBzcF9uYW1lID0gZmN0X3Jlb3JkZXIoc3BfbmFtZSwgY3RtYXgsIG1lYW4pKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gc3BfbmFtZSwgeCA9IGN0bWF4KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXI9IHNwX25hbWVfc3ViKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjMpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgeGxhYihOVUxMKSArIAogIGxhYnMoeSA9ICIiLAogICAgICAgeCA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiR3JvdXAiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnNpemVfcGxvdCA9IGZ1bGxfZGF0YSAlPiUgCiAgbXV0YXRlKHNwX25hbWUgPSBmY3RfcmVvcmRlcihzcF9uYW1lLCBjdG1heCwgbWVhbikpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBzcF9uYW1lLCB4ID0gc2l6ZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyPSBzcF9uYW1lX3N1YiksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4zKSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHkgPSAiIiwgCiAgICAgICBjb2xvdXIgPSAiR3JvdXAiKSArIAogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChuY29sID0gMSkpICsKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9ICkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAsIDAsIDAsIDAsImNtIikpCgp0cmFpdF9wbG90ID0gY3RtYXhfcGxvdCArIHNpemVfcGxvdAp0cmFpdF9wbG90CmBgYAoKYGBge3IgY3RtYXgtYW5kLXNpemUtaGlzdG9ncmFtcywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MjEsIGluY2x1ZGUgPSBGfQpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNpemUsIGZpbGwgPSBzcF9uYW1lX3N1YikpICsgCiAgZmFjZXRfd3JhcCgufnNwX25hbWVfc3ViLCBuY29sID0gMSkgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDUpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJQcm9zb21lIGxlbmd0aCAobW0pIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQoKZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjdG1heCwgZmlsbCA9IHNwX25hbWVfc3ViKSkgKyAKICBmYWNldF93cmFwKC5+c3BfbmFtZV9zdWIsIG5jb2wgPSAxKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkNUbWF4ICjCsEMpIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyIGZlY3VuZGl0eS1oaXN0b2dyYW0sIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTEwfQpmdWxsX2RhdGEgJT4lICAKICBkcm9wX25hKGZlY3VuZGl0eSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBmZWN1bmRpdHksIGZpbGwgPSBzcF9uYW1lX3N1YikpICsgCiAgZmFjZXRfd3JhcCgufnNwX25hbWVfc3ViLCBuY29sID0gMSkgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDIpICsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIGxhYnMoeCA9ICJGZWN1bmRpdHkgKCMgRWdncykiKSArCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgojIyMgVmFyaWF0aW9uIHdpdGggdGVtcGVyYXR1cmUgCgpgYGB7ciB0cmFpdC1jb2xsLXRlbXAtcGxvdHMsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KY3RtYXhfdGVtcCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKc2l6ZV90ZW1wID0gZ2dwbG90KGZpbHRlcihmdWxsX2RhdGEsIHNleCAhPSAianV2ZW5pbGUiKSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBzaXplLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsaW5ld2lkdGggPSAzKSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJMZW5ndGggKG1tKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgp3dF90ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSB3YXJtaW5nX3RvbCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGluZXdpZHRoID0gMykgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIHkgPSAiV2FybWluZyBUb2xlcmFuY2UgKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSAgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZWdnc190ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBmZWN1bmRpdHksIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfdGVtcCwgc2l6ZV90ZW1wLCB3dF90ZW1wLCBlZ2dzX3RlbXAsIAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJyaWdodCIpCmBgYAoKYGBge3IgY3RtYXgtY29sbC10ZW1wLW1vZGVsfQpjdG1heF90ZW1wLm1vZGVsID0gbG0oZGF0YSA9IGZ1bGxfZGF0YSwgY3RtYXggfiBjb2xsZWN0aW9uX3RlbXAgKiBzcF9uYW1lKQoKa25pdHI6OmthYmxlKGNhcjo6QW5vdmEoY3RtYXhfdGVtcC5tb2RlbCkpCgpjdG1heF9yZXNpZHMgPSBjYmluZChmdWxsX2RhdGEsICJyZXNpZHMiID0gY3RtYXhfdGVtcC5tb2RlbCRyZXNpZHVhbHMpCmBgYAoKYGBge3IgY3RtYXgtdGltZS1pbi1sYWIsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KZ2dwbG90KGN0bWF4X3Jlc2lkcywgYWVzKHggPSBkYXlzX2luX2xhYiwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMDozKSkgKyAKICBsYWJzKHggPSAiRGF5cyBpbiBsYWIiLCAKICAgICAgIHkgPSAiQ1RtYXggUmVzaWR1YWxzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCkdpdmVuIHRoZSBsb25nIGdlbmVyYXRpb24gdGltZXMgb2YgdGhlc2UgY29wZXBvZHMsIGRlY3JlYXNlcyBpbiB0cmFpdCB2YXJpYW5jZSBtYXkgaW5kaWNhdGUgc2VsZWN0aW9uIG92ZXIgdGhlIHNlYXNvbmFsIGN5Y2xlLiBTaG93biBiZWxvdyBhcmUgdGhlIHZhcmlhbmNlIGluIG9ic2VydmVkIENUbWF4IGFuZCBzaXplLCBwbG90dGVkIGFnYWluc3QgY29sbGVjdGlvbiBkYXRlLiBWYXJpYW5jZSBkZWNyZWFzZXMgaW4gKlNraXN0b2RpYXB0b211cyosIGJ1dCB0aGlzIHBhdHRlcm4gaXMgZHJpdmVuIGJ5IGEgc2luZ2xlIGNvbGxlY3Rpb24gd2l0aCBoaWdoIHZhcmlhbmNlIGVhcmx5IGluIHRoZSB5ZWFyLiBTaXplIHZhcmlhbmNlIGluY3JlYXNlcyBzbGlnaHRseSBpbiAqU2tpc3RvZGlhcHRvbXVzKi4gVmFyaWFuY2UgaW4gYm90aCBDVG1heCBhbmQgc2l6ZSBpcyBmYWlybHkgY29uc3RhbnQgaW4gKkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMqLCB0aGUgb25seSBvdGhlciBzcGVjaWVzIGNvbGxlY3RlZCBhY3Jvc3MgdGhlIGVudGlyZSBzZXQgb2Ygc2FtcGxlcyB0aHVzIGZhci4gCgpgYGB7ciB0cmFpdC12YXJpYW5jZS1jb2xsLXRlbXB9CmdncGxvdChkcm9wX25hKHNwZWNpZXNfc3VtbWFyaWVzLCBjdG1heF92YXIpLCBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKICAgICAgIHkgPSAiQ1RtYXggVmFyaWFuY2UiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpnZ3Bsb3QoZHJvcF9uYShzcGVjaWVzX3N1bW1hcmllcywgc2l6ZV92YXIpLCBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IHNpemVfdmFyLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRikgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsIAogICAgICAgeSA9ICJTaXplIFZhcmlhbmNlIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCgojIyBTZXggYW5kIHN0YWdlIHZhcmlhdGlvbiBpbiB0aGVybWFsIGxpbWl0cyAKUHJldmlvdXMgc2VjdGlvbnMgaGF2ZSBnZW5lcmFsbHkgbHVtcGVkIGp1dmVuaWxlLCBmZW1hbGUsIGFuZCBtYWxlIGluZGl2aWR1YWxzIHRvZ2V0aGVyLiBUaGVyZSBtYXkgYmUgaW1wb3J0YW50IHN0YWdlLSBvciBzZXgtc3BlY2lmaWMgZGlmZmVyZW5jZXMgaW4gQ1RtYXggdGhvdWdoLiBGb3Igc2V2ZXJhbCBzcGVjaWVzLCB3ZSBoYXZlIG1lYXN1cmVtZW50cyBmb3IgaW5kaXZpZHVhbHMgaW4gZGlmZmVyZW50IHN0YWdlcyBvciBvZiBkaWZmZXJlbnQgc2V4ZXMuIAoKYGBge3Igc2V4LXN0YWdlLXRhYmxlfQpzZXhfc2FtcGxlX3NpemVzID0gY3RtYXhfcmVzaWRzICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSwgc2V4KSAlPiUgIAogIHN1bW1hcmlzZShudW0gPSBuKCkpICU+JSAgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IHNwX25hbWUsCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNleCwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBudW0sCiAgICAgICAgICAgICAgdmFsdWVzX2ZpbGwgPSAwKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJKdXZlbmlsZSIgPSBqdXZlbmlsZSwgIkZlbWFsZSIgPSBmZW1hbGUsICJNYWxlIiA9IG1hbGUpCgprbml0cjo6a2FibGUoc2V4X3NhbXBsZV9zaXplcywgYWxpZ24gPSAiYyIpCmBgYAoKVGhlIGZlbWFsZS1tYWxlIGFuZCBmZW1hbGUtanV2ZW5pbGUgY29tcGFyaXNvbnMgc2hvdyB0aGF0IHRoZXJlIGFyZSBnZW5lcmFsbHkgbm8gZGlmZmVyZW5jZXMgaW4gdGhlcm1hbCBsaW1pdHMgYmV0d2VlbiB0aGVzZSBncm91cHMuIAoKYGBge3IgY3RtYXgtc2V4LCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgZmlsdGVyKHNleF9zYW1wbGVfc2l6ZXMsIE1hbGUgPiAwLCBGZW1hbGUgPiAwKSRTcGVjaWVzICYgCiAgICAgICAgICAgc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzZXgsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUsIGdyb3VwID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoZWlnaHQgPSAwLCB3aWR0aCA9IDAuMDUpKSArICAKICBsYWJzKHggPSAiU2V4IiwgCiAgICAgICB5ID0gIkNUbWF4IFJlc2lkdWFscyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyIGN0bWF4LXN0YWdlLCBmaWcud2lkdGg9MywgZmlnLmhlaWdodD02fQpjdG1heF9yZXNpZHMgJT4lIAogIGZpbHRlcihzcF9uYW1lICVpbiUgZmlsdGVyKHNleF9zYW1wbGVfc2l6ZXMsIEp1dmVuaWxlID4gMCAmIEZlbWFsZSA+IDApJFNwZWNpZXMgJiAKICAgICAgICAgICBzZXggIT0gIm1hbGUiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gc2V4LCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lLCBncm91cCA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDEpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIoaGVpZ2h0ID0gMCwgd2lkdGggPSAwLjA1KSkgKyAgCiAgbGFicyh4ID0gIlNleCIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMTgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpKQpgYGAKCiMjIFRyYWl0IENvcnJlbGF0aW9ucyAKCmBgYHtyIGN0bWF4LXNpemUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03fQpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGZ1bGxfZGF0YSwgCiAgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gY3RtYXgpLAogICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICAgICAgICAgICAgIGNvbG91ciA9ImJsYWNrIiwgCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMi41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0KSArIAogIGxhYnMoeCA9ICJMZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpgYGB7ciBjdG1heHJlc2lkcy1zaXplLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NywgaW5jbHVkZSA9IEZ9CmdncGxvdChjdG1heF9yZXNpZHMsIGFlcyh4ID0gc2l6ZSwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGN0bWF4X3Jlc2lkcywgCiAgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gcmVzaWRzKSwKICAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAgICAgICAgICAgICBjb2xvdXIgPSJibGFjayIsIAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIuNSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKCmBgYHtyIGZlY3VuZGl0eS1zaXplLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KZ2dwbG90KGN0bWF4X3Jlc2lkcywgYWVzKHggPSBzaXplLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gNCkgKyAKICBsYWJzKHggPSAiUHJvc29tZSBsZW5ndGggKG1tKSIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IsIGN0bWF4LWZlY3VuZGl0eSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTd9CmdncGxvdChjdG1heF9yZXNpZHMsIGFlcyh4ID0gY3RtYXgsIHkgPSBmZWN1bmRpdHksIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0KSArIAogIGxhYnMoeCA9ICJDVG1heCAowrBDKSIsIAogICAgICAgeSA9ICJGZWN1bmRpdHkgKCMgRWdncykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKCg==